<?php
/**
 * $Date: 2010-08-12 19:51:22 +0000 (Thu, 12 Aug 2010) $
 * $Author: manuelcanepa@gmail.com $
 * $Revision: 3 $
 * $URL: http://librerias-utiles.googlecode.com/svn/trunk/librerias-utiles/app/default/views/helpers/Thumb.php $
 */
class Zend_View_Helper_Thumb extends Zend_View_Helper_Abstract
{
    const ERROR_DIR_CACHE_PERMISOS = "Imposible crear directorio de cache, verifique los permisos '%s' ";
    const ERROR_DIR_CACHE = "Directorio de imagenes incorrecto '%s'";
    const DIR_CACHE = '/media/cache/';

    protected $_pref = '';
    protected $path = '';
    protected $_url_path = '';
    protected $_dir = IMG_PATH;
    protected $params = null;
    protected $_def_params = array(
        'alt' => '',
        'ancho' => '%',
        'alto' => '%',
        'aspecto' => true,
        'src' => false,
        'server' => true,
        'r' => 233,
        'g' => 229,
        'b' => 226,
        'nombre' => '',
        'default' => '/img/logo.png',
        'id' => '',
        'rel' => '',
        'class' => ''
    );

    function thumb($path, $args=array())
    {
        if ($this->params === null)
        {
            $this->params = $this->_def_params;
        }

        $this->path = $path;
        $args = array_merge(
                        $this->_def_params,
                        $args
        );
        $locale = setlocale(LC_CTYPE, 'es_ES.utf8');
        $args['alt'] = @iconv(iconv_get_encoding($args['alt']), 'ASCII//IGNORE', $args['alt']);
        setlocale(LC_CTYPE, $locale);

        $this->setParams($args);

#		  if( $this->getParam('name')!== null)
#				$this->path = preg_replace('/\.(\w+)$/', '/'.$this->getParam('name').'.$1', $this->path);

        $this->_url_path = self::DIR_CACHE;
        $src = $this->creaCache();
        if ($src == false)
        {
            if ($this->getParam('src') === true)
            {
                return $this->serverUrl() . $this->getParam('default');
            } else
            {
                return <<<IMG
        <img src="{$this->serverUrl()}{$this->getParam('default')}" {$this->inline()} />
IMG;
            }
        } else
        {
            if ($this->getParam('src') === true)
            {
                return $this->serverUrl() . $src;
            } else
            {
                return <<<IMG
        <img src="{$this->serverUrl()}{$src}" {$this->inline()} />
IMG;
            }
        }
    }

    public function inline()
    {
        $html = array();
        foreach (array('id', 'class', 'alto', 'ancho', 'alt', 'rel') as $param)
        {
            $valor = $this->getParam($param);
            if ($valor == '')
            {
                continue;
            }
            switch ($param)
            {
                case 'alto':
                    $param = 'height';
                    break;
                case 'ancho':
                    $param = 'width';
                    break;
            }
            $html[] = sprintf('%s="%s"', $param, $valor);
        }
        return implode(' ', $html);
    }

    protected function creaCache()
    {
        /**
         * Traigo la ruta de donde va a sacar los walls
         */
        $src = $this->_dir;
        if ($src == false)
        {
            //			trigger_error(sprintf(self::ERROR_DIR_CACHE,$this->_dir));
        }

        /**
         * Si no existe el archivo retorno falso
         */
        $src = $src . $this->path;
        if (!is_file($src) || !is_readable($src))
        {
            return false;
        }

        /**
         * Si son medidas validas redimensiono
         */
        $tam = getimagesize($src);
        $src_w = $tam[0];
        $src_h = $tam[1];
        $percent = 0;
        if ($this->validarMedida($this->getParam('ancho'), $this->getParam('alto')))
        {
            /**
             * Si el ancho o el alto no es cero redimensiono
             */
            if ($this->getParam('ancho') == '%')
            {
                $percent = ($this->getParam('alto') * 100) / $src_h;
                $this->setParam('ancho', intval(($percent * $src_w) / 100));
            } elseif ($this->getParam('alto') == '%')
            {
                $percent = ($this->getParam('ancho') * 100) / $src_w;
                $this->setParam('alto', intval(($percent * $src_h) / 100));
            }
        } elseif ($this->getParam('ancho') == '%' && $this->getParam('ancho') == '%')
        {
            /**
             * No crea thumbsnails mas grandes de 1024x1024
             */
            if ($src_w > 1024 || $src_h > 1024)
            {
                if ($src_w > $src_h)
                {
                    $this->setParam('ancho', 1024);
                    $this->setParam('alto', 1024 * ($src_h / $src_w));
                } else
                {
                    $this->setParam('ancho', 1024 * ($src_w / $src_h));
                    $this->setParam('alto', 1024);
                }
            } else
            {
                $this->setParam('ancho', $src_w);
                $this->setParam('alto', $src_h);
            }
        }

        $this->setPrefix();

        if ($this->existe())
        {
            return $this->urlPath();
        }

        $mtype = mime_content_type($src);
        switch ($mtype)
        {
            case 'image/png':
                $img = imagecreatefrompng($src);
                break;
            case 'image/gif':
                $img = imagecreatefromgif($src);
                break;
            case 'image/jpeg':
                $img = imagecreatefromjpeg($src);
                break;
            default:
                if ($img = @imagecreatefrompng($src))
                {
                    $mtype = 'image/png';
                } elseif ($img = @imagecreatefromgif($src))
                {
                    $mtype = 'image/gif';
                } elseif ($img = @imagecreatefromjpeg($src))
                {
                    $mtype = 'image/jpeg';
                } elseif ($img = @imagecreatefromwbmp($src))
                {
                    $mtype = 'image/wbmp';
                } elseif ($img = @imagecreatefromgd($src))
                {
                    $mtype = 'image/gd';
                } else
                {
                    return false;
                    throw new Exception(sprintf("Invalid Mime '%s' en '%s'", $mtype, $src));
                }
                break;
        }

        /**
         * Retorno el src si existe
         */
        $dst = $this->destino($this->getParam('ancho'), $this->getParam('alto'));
        $dx = $dy = 0;
        $sw = $w = $this->getParam('ancho');
        $sh = $h = $this->getParam('alto');
        if ($this->getParam('aspecto') === true)
        {
            if ($src_w > $src_h)
            {
                $percent = ($sw * 100) / $src_w;
                $h = intval(($percent * $src_h) / 100);
                $dy = intval(($sh / 2) - ($h / 2));
            } else
            {
                $percent = ($sh * 100) / $src_h;
                $w = intval(($percent * $src_w) / 100);
                $dx = intval(($sw / 2) - ($w / 2));
            }
        }

        imagecopyresampled(
                $dst, // Imagen de destino
                $img, // Source de imagen
                $dx, // Posicion x destino
                $dy, // Posicion y destino
                0, // Posicion x source
                0, // Posicion y source
                $w, // Ancho destino
                $h, // Alto Destino
                $src_w, // Ancho Source
                $src_h  // Alto Source
        );
        unset($img);

        imageinterlace($dst, true);
        imagealphablending($dst, true);
        imagesavealpha($dst, true);

        $dir = $this->dirBase();
        $fi = $dir . $this->getName();
        if (!is_dir(dirname($fi)))
        {
            @mkdir(dirname($fi), 0777, true);
        }
        switch ($mtype)
        {
            case 'image/png':
                imagepng($dst, $fi, 0);
                break;
            case 'image/gif':
                imagegif($dst, $fi);
                break;
            case 'image/jpeg':
                imagejpeg($dst, $fi, 100);
                break;
            case 'image/wbmp':
                image2wbmp($dst, $fi, 255);
                break;
            case 'image/gd':
                imagegd($dst, $fi);
                break;
        }
        imagedestroy($dst);
        return $this->urlPath();
    }

    public function urlPath()
    {
        return $this->_url_path . $this->getName();
    }

    protected function setPrefix($logo = false)
    {
        if ($logo === false)
        {
            $this->_url_path .= "{$this->getParam('ancho')}/{$this->getParam('alto')}/";
        }
        $this->_pref = "{$this->getParam('ancho')}x{$this->getParam('alto')}-";
        if ($this->getParam('aspecto'))
        {
            $this->_pref = 'kp' . $this->_pref;
        } else
        {
            $this->_pref = 'nk' . $this->_pref;
        }
        $aux = explode('/', $this->getName());
        if (count($aux) > 0)
        {
            $aux = preg_replace('/[^a-z0-9-_\.]/i', '-', $aux);
            $aux = str_split($aux[count($aux) - 1]);
            $aux = implode('/', $aux);
            $aux = substr($aux, 0, 3);
            $this->_url_path .= $aux . '/';
            unset($aux);
        }

        return $this;
    }

    public function setParams($args)
    {
        foreach ($args as $key => $val)
        {
            $this->setParam($key, $val);
        }
        return $this;
    }

    public function getParam($key)
    {
        if (isset($this->params[$key]))
        {
            return $this->params[$key];
        }
        return '';
    }

    public function setParam($key, $val)
    {
        if (isset($this->params[$key]))
        {
            $this->params[$key] = $val;
        }
        return $this;
    }

    public function validarMedida($ancho, $alto)
    {
        if (
                (is_numeric($ancho) && is_numeric($alto))
                || (is_numeric($ancho) && $alto == '%')
                || (is_numeric($alto) && $ancho == '%')
        )
        {
            return true;
        }
        return false;
    }

    public function destino($ancho, $alto)
    {
        $dst = imagecreatetruecolor($ancho, $alto);
        $transparente = imagecolorallocate($dst, $this->getParam('r'), $this->getParam('g'), $this->getParam('b'));
        imagefill($dst, 0, 0, $transparente);
        imagecolortransparent($dst, $transparente);
        return $dst;
    }

    protected function dirBase()
    {
        $dir = DOC_ROOT . $this->_url_path;
        return $dir;
    }

    protected function tag()
    {
        return preg_replace('/[^a-z0-9-_\.]/i', '-', $this->path);
    }

    public function existe()
    {
        if (is_file($this->dirBase() . $this->getName()))
        {
            if (filectime($this->dirBase() . $this->getName()) > filectime(__FILE__))
            {
                return true;
            }
        }
        return false;
    }

    private function serverUrl()
    {
        return ($this->getParam('server')) ? $this->view->urlStatica() : '';
        return ($this->getParam('server')) ? $this->view->serverUrl() : '';
    }

    public function getName()
    {
        if ($this->getParam('nombre') !== '')
        {
            $nombre = preg_replace('/[\/\\\*\?\"\<\>\|\\:]+/', '-', $this->getParam('nombre'));
            return preg_replace('/.*\.(\w+)$/', $nombre . '.$1', $this->path);
        } else
        {
            return $this->path;
        }
    }
}
if (!function_exists('mime_content_type'))
{

    function mime_content_type($filename)
    {

        $mime_types = array(
            'txt' => 'text/plain',
            'htm' => 'text/html',
            'html' => 'text/html',
            'php' => 'text/html',
            'css' => 'text/css',
            'js' => 'application/javascript',
            'json' => 'application/json',
            'xml' => 'application/xml',
            'swf' => 'application/x-shockwave-flash',
            'flv' => 'video/x-flv',
            // images
            'png' => 'image/png',
            'jpe' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'jpg' => 'image/jpeg',
            'gif' => 'image/gif',
            'bmp' => 'image/bmp',
            'ico' => 'image/vnd.microsoft.icon',
            'tiff' => 'image/tiff',
            'tif' => 'image/tiff',
            'svg' => 'image/svg+xml',
            'svgz' => 'image/svg+xml',
            // archives
            'zip' => 'application/zip',
            'rar' => 'application/x-rar-compressed',
            'exe' => 'application/x-msdownload',
            'msi' => 'application/x-msdownload',
            'cab' => 'application/vnd.ms-cab-compressed',
            // audio/video
            'mp3' => 'audio/mpeg',
            'qt' => 'video/quicktime',
            'mov' => 'video/quicktime',
            // adobe
            'pdf' => 'application/pdf',
            'psd' => 'image/vnd.adobe.photoshop',
            'ai' => 'application/postscript',
            'eps' => 'application/postscript',
            'ps' => 'application/postscript',
            // ms office
            'doc' => 'application/msword',
            'rtf' => 'application/rtf',
            'xls' => 'application/vnd.ms-excel',
            'ppt' => 'application/vnd.ms-powerpoint',
            // open office
            'odt' => 'application/vnd.oasis.opendocument.text',
            'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
        );

        $ext = strtolower(array_pop(explode('.', $filename)));
        if (array_key_exists($ext, $mime_types))
        {
            return $mime_types[$ext];
        } elseif (function_exists('finfo_open'))
        {
            $finfo = finfo_open(FILEINFO_MIME);
            $mimetype = finfo_file($finfo, $filename);
            finfo_close($finfo);
            return $mimetype;
        } else
        {
            return 'application/octet-stream';
        }
    }
}